#!/usr/bin/env python
# -*- coding: utf-8 -*-
# File  :jingdong_shopV2.py
# Time  :广州总公司-广州子公司-2025/1/9 13:39
# Email :fortunatedong@163.com
# Author:by Adonli
import random
import time
import re
from wsgiref import headers

import requests
import json

from playwright.sync_api import sync_playwright
from dingding_guotie_jd.get_jingdong_cookies import jingdong_login
from dingding_guotie_jd.jingdong_verify import jingdong_verify
from dingding_guotie_jd.settings.error_handler import retry_on_exception
from dingding_guotie_jd.settings.logger import Loggings
logs = Loggings()

# class jingdong_login():
#     def __init__(self,pw):
#         self.browser = pw.chromium.launch(headless=False, channel="chrome")
#         self.context = self.browser.new_context()
#         self.page = self.context.new_page()
#     @retry_on_exception(max_retries=3,delay=2)
#     def save_jingdong_cookie(self):
#         self.page.goto("https://passport.jd.com/new/login.aspx")
#         self.page.locator("input[id='loginname']").fill("xxxxxxxxxxxxxx")
#         self.page.locator("input[id='nloginpwd']").fill("xxxxxxxxxxxxxxxx")
#         self.page.wait_for_timeout(3000)
#         self.page.locator("a[id='loginsubmit']").click()
#         self.page.wait_for_timeout(10000)
#         # storage = self.context.storage_state(path="auth/state.json")
#         cookies = self.context.cookies()
#         # 保存 Cookie 到文件
#         with open('auth/cookies.json', 'w') as f:
#             json.dump(cookies, f)
#         self.page.wait_for_timeout(10000)
#         # print(storage)

class GetJingDongPrice():
    def __init__(self, pw,shopid, shopname, keywords):
        self.pw = pw
        self.shopid = shopid
        self.keywords = keywords
        self.shopname = shopname
        self.url = "https://module-jshop.jd.com/module/getModuleHtml.html"
        self.header = {
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
            "cookie": "__jdu=17339734656861643552330; shshshfpa=08510fe5-3f1b-0f54-8a74-ebca4a55cdb9-1733898953; shshshfpx=08510fe5-3f1b-0f54-8a74-ebca4a55cdb9-1733898953; user-key=c230cc4e-ee51-49f6-ba5c-c06ad289be2c; pinId=DMJ2clovqsZTeIWaW9x3kg; _tp=40u6lCBCuQbWIwgXQY5Xbg%3D%3D; _pst=jd_aqrAaxqwcjCq; TrackID=1uClOlIu7xPWL2KX2HSak8aQ63u9Zm-G2XOBehe9nwGPSgNE5RI1K0dPQ-JxM-EbapVODh2_z5-FPXJj8DUcMx7S6bNzkOCnSah3AFRGJ9XE; thor=6AC20EBE544051F9ED77A0988EFD087AB17FF26D3810FCFD448DCA23645460CF7699D16E650E4DB5A350B9519D9AE02487DA816D0252855459D6C764DD73FF3AE293FE1751D876F54ECF45FB76445B9E3AC982D4C68DBB047B758B2280E04815DCD8D70C8C48D2849461776760507165A6BDE596AD74EE81CBCAB2CB317994750DFA09C5E29B7108543280558B07BCF819D2A763E888188749137DA9E4633C27; light_key=AASBKE7rOxgWQziEhC_QY6yavlDomujUxm6UGlTmxsspmefjR6BDBldmeKgvmUoS1GuYejel; pin=jd_aqrAaxqwcjCq; unick=72lx0jp5zsw3jw; ceshi3.com=000; unpl=JF8EALRnNSttWU8DVUkCE0VFS1gDWw1aSx4Db28BVlsLGVcCHQtLFEB7XlVdWRRKFx9uYBRUWFNOVg4ZBCsSEXteU11bD00VB2xXVgQFDQ8WUUtBSUt-S1tXV1QOSh4AbGQBZG1bS2QFGjIbFBJJVVJcWA9PEApoZwJRX1xPVwcZAysTIExtZG5dC04SAmhXBGRcaAkAWRIKGBoSQhBUWF8KQxEBamABU1RfS1MAGQYfERJJXGRfbQs; __jdv=229668127|baidu-search|t_262767352_baidusearch|cpc|172887082225_0_05fac19fd14f4ac18119537bc2678a7a|1736145818865; areaId=19; ipLoc-djd=19-1601-50258-129167; cn=2; mt_xid=V2_52007VwMUUF9QVFgaTh1bDGADFVdfXFZZHUsYbFIyVBMHXVpWRh1PEQ8ZYgQQUkEIUlxIVRpbA2ULQQVdUVpZGXkaXQZjHxNSQVlVSx9MElkBbAERYl9oUWocSB9UAGIzEVVdXg%3D%3D; PCSYCityID=CN_440000_440100_0; _base_=YKH2KDFHMOZBLCUV7NSRBWQUJPBI7JIMU5R3EFJ5UDHJ5LCU7R2NILKK5UJ6GLA2RGYT464UKXAI4JUXB7M672MZOT6FGO2MU2LUEVYDFCBDLSNUNIIHDIWP7JNTPUCBL6QL2UK5TPMNUH3BSRQJISYQQ3XGMUXPD5XUXEKW3Z6KPYGEG4MNVVVKEJAEYVSRDE6GTYSO6Y3RHU2WJTJ7KKW35UYR6GUM3EQNUX6VYZG6SK3UVKRC746B54SN2MIFVKGS5LS45CPYVDNFYKOXCX47C2N37UB77MTOYX2UK65DZVNAAWXAUYFJHE3A25HWTHSEPO5HAL4NSCIIEAYA62VTXNH74DN7ZZ3JUAVDNZV7BAGHNUGCVIEBTO3CTG766OWCJNRS5KFUFDTZJWRGOWZSKTISWJEMZXMIBF56JMULJYOMSIOGGSVOGJKP6NY5TTSTRESIASLTLRLGOZOMWTKGZQUDE4BYUFHK2BF464FWQ4QLFFFDEEIJHRHHNO4BQ5AALQTWYM525FQENLQWUSWHIM; b_belong=CNP254STAZVTRYKM3UUWRWHOCEHMZUSJ75VAEFWWXFPVCB4ASEE2KRMYID5U72G3FGHIKTSQT5BUQOPZ6HKVNQG7GXKL2S4ADXCYYYTX535EPHNKEFZ5JLITHUBHETRXPMQDT36KPH27N7JSTMB3ZIXNRCDWT3VBRACH2V4VSVZ4E56DSO62SM7LVAWROWWH; umc_count=1; jsavif=1; token=aa3204c3da66833b9b6f026b7aeccd32,3,964667; __jda=94967808.17339734656861643552330.1733973466.1736389066.1736402190.54; __jdc=94967808; 3AB9D23F7A4B3CSS=jdd03KFZ3X6LBGPKCSNK4ST35NBOQH3WNRFOJH6ILTYM4PZ44E2LXOXW6W2CYCX27333MVQAWFSNHFRRGRQ4W7BZBPSQLRIAAAAMUJG7BUMYAAAAADBSBJ4ERUQA7VIX; JSESSIONID=293F691723F1E86ABA4D39AB78A1B441.s1; 3AB9D23F7A4B3C9B=KFZ3X6LBGPKCSNK4ST35NBOQH3WNRFOJH6ILTYM4PZ44E2LXOXW6W2CYCX27333MVQAWFSNHFRRGRQ4W7BZBPSQLRI; shshshfpb=BApXSW4i2SvFAp6H1zVzh4Di9gr3xk3xjBnHIjnxn9xJ1MmQJRIG2; hf_time=1736421979826; flash=3_JG7BSlHBQrc4Y8qsa_XZaYMlkJ0xzy0KPKeYX6B25S_oIccQHIG_yNcGWQuBkZG2_7izGGunG340HRH-5VIZ1uIWpHV3MOoDLkcCmezRH-DgmXfxh-HKS8ZtzyTZJ7H8xO6pnHlEFA-3f6Yv; __jdb=94967808.9.17339734656861643552330|54.1736402190",
            "referer": "https://mall.jd.com/"
        }

    @retry_on_exception(max_retries=3, delay=2)
    def text_replace(self,html_text):
        return html_text.replace("	", "").replace("\r", "").replace("\n", "").replace("\\", "").replace("\t", "")

    @retry_on_exception(max_retries=3, delay=2)
    def extract_last_render_attributes(self,html_content):
        # 创建匹配模式
        pattern = r'm_render_pageInstance_id="([^"]*)"\s*'
        pattern += r'm_render_app_id="([^"]*)"\s*'
        pattern += r'm_render_origin="([^"]*)"\s*'
        pattern += r'm_render_layout_instance_id="([^"]*)"\s*'
        pattern += r'm_render_prototype_id="([^"]*)"\s*'
        pattern += r'm_render_template_id="([^"]*)"\s*'
        pattern += r'm_render_instance_id="([^"]*)"\s*'
        pattern += r'm_render_is_search="([^"]*)"'

        # 找到所有匹配项
        matches = re.findall(pattern, html_content)

        # 如果有匹配项，只返回最后一个
        if matches:
            last_match = matches[-1]
            result = {
                "pageInstance_id": last_match[0],
                "app_id": last_match[1],
                "origin": last_match[2],
                "layout_instance_id": last_match[3],
                "prototype_id": last_match[4],
                "template_id": last_match[5],
                "instance_id": last_match[6],
                "is_search": last_match[7]
            }
            return result
        return None

    @retry_on_exception(max_retries=3, delay=2)
    def get_request_param(self):
        url = f"https://mall.jd.com/index-{self.shopid}.html"
        response_code = requests.get(url, headers=self.header)
        response_text = response_code.text
        response_result = self.text_replace(response_text)
        jingdong_url_appId = re.compile(r'<input type="hidden" value="(.*?)" id="pageInstance_appId"',re.S)
        appId = re.findall(jingdong_url_appId, response_result)
        if len(appId) == 0:
            logs.error("正则匹配获取URL参数appId错误！请检查源代码元素是否改动")
        jingdong_url_vender_id = re.compile(r'<input type="hidden" id="vender_id" value="(.*?)"', re.S)
        vender_id = re.findall(jingdong_url_vender_id, response_result)
        if len(vender_id) == 0:
            logs.error("正则匹配获取URL参数vender_id错误！请检查源代码元素是否改动")
        jingdong_url_shop_id = re.compile(r'<input type="hidden" id="shop_id" value="(.*?)"', re.S)
        shop_id = re.findall(jingdong_url_shop_id, response_result)
        if len(vender_id) == 0:
            logs.error("正则匹配获取URL参数shop_id错误！请检查源代码元素是否改动")
        logs.info(f"appId:{appId}, vender_id:{vender_id}, shop_id:{shop_id}")
        jingdong_url = f"https://mall.jd.com/view_search-{appId[0]}-{vender_id[0]}-{shop_id[0]}-0-0-0-0-1-1-60.html"
        logs.info(f"京东搜索页面URL：jingdong_url={jingdong_url}")
        response_param_code = requests.get(jingdong_url, headers=self.header)
        response_param_text = response_param_code.text
        # print(response_param_text)
        response_param_result = self.text_replace(response_param_text)
        param_result = self.extract_last_render_attributes(response_param_result)
        param_result["vender_id"] = vender_id[0]
        param_result["shop_id"] = shop_id[0]
        logs.info(f"param_result:{param_result}")
        return param_result

    @retry_on_exception(max_retries=3, delay=2)
    def request_param(self,page_item_count=1):
        param_result = self.get_request_param()
        param = {
            "other":"",
            "isGlobalSearch":0,
            "venderId": param_result["vender_id"],
            "orderBy": 0,
            "pageSize": 60,
            "pageNo": page_item_count,
            "pagePrototypeId": "",
            "appId": param_result["app_id"],
            "minPrice": 0,
            "shopId": self.shopid,
            "maxPrice": 0,
            "keyword": self.keywords,
            "categoryId": 0,
            "direction": 1,
            "pageInstanceId": param_result["pageInstance_id"],
            "moduleInstanceId": param_result["layout_instance_id"],
            "prototypeId":  param_result["prototype_id"],
            "templateId":  param_result["template_id"],
            "layoutInstanceId":  param_result["layout_instance_id"],
            "origin": 0,
            "callback": "jshop_module_render_callback",
            "_": int(round(time.time() * 1000))
        }
        return param

    @retry_on_exception(max_retries=3, delay=2)
    def re_grexp(self,response_text):
        response_result = response_text.replace(" ", "").replace("\\r", "").replace("\\n", "").replace("\\", "")

        jingdong_sku_pattern = re.compile(r'<lidata-href=\"(.*?)\"data-src=\".*?\"sid=\"(.*?)\"><atitle=\"(.*?)\"class=\"\"href=\"javascript:;\">',re.S)
        jingdong_sku_result = re.findall(jingdong_sku_pattern, response_result)
        jingdong_skus_urls = []
        for jingdong_sku in jingdong_sku_result:
            jingdong_skus_urls.append(list(jingdong_sku))


        jingdong_sku_count_pattern = re.compile(r'找到<em>(.*?)</em>件商品',re.S)
        jingdong_sku_count_result = re.findall(jingdong_sku_count_pattern, response_result)
        jingdong_sku_count_result = int(jingdong_sku_count_result[0])

        return jingdong_skus_urls,jingdong_sku_count_result

    @retry_on_exception(max_retries=3, delay=2)
    def get_jingdong_skus_urls(self):
        logs.info(f"开始首页数据调用请求")
        response = requests.get(url=self.url,params=self.request_param(),headers=self.header)
        response_text = response.text

        jingdong_skus_urls,jingdong_sku_count_result = self.re_grexp(response_text)
        # print(jingdong_sku_result)
        # print(jingdong_sku_count_result)


        if jingdong_sku_count_result > 15:
            jingdong_sku_count_result = 15


        if jingdong_sku_count_result % 60 == 0:
            page_item_count = jingdong_sku_count_result // 60 + 1
        else:
            page_item_count = jingdong_sku_count_result // 60 + 2
        logs.info(f"搜索结果{page_item_count - 1}页")
        if page_item_count > 2:
            for i in range(2,page_item_count):
                logs.info(f"开始第{i}页数据调用请求")
                response = requests.get(url=self.url, params=self.request_param(i), headers=self.header)
                response_text = response.text
                jingdong_skus_temp, jingdong_sku_count_result_temp = self.re_grexp(response_text)
                for j in jingdong_skus_temp:
                    jingdong_skus_urls.append(j)
        logs.info(f"搜索{page_item_count - 1}页商品，共计搜索{len(jingdong_skus_urls)}个SKU")
        logs.info(jingdong_skus_urls)
        return jingdong_skus_urls

    def get_sku_price(self,sku):
        count = 0
        while count < 100:
            try:
                # response = requests.get(url="https:"+url, headers=self.header)
                url=f"https://item.jd.com/{sku}.html"
                self.browser = self.pw.chromium.launch(headless=True, channel="chrome")
                self.context = self.browser.new_context(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36")
                with open('auth/jingdong_cookies.json', 'r') as f:
                    cookies = json.load(f)
                # print(cookies)
                self.context.add_cookies(cookies)
                self.page = self.context.new_page()
                self.page.set_extra_http_headers({
                    "Accept-Language": "en-US,en;q=0.9",
                    "Referer": "https://www.jd.com/"
                })
                with open('auth/stealth.min.js', 'r') as f:
                    js = f.read()
                self.page.add_init_script(js)

                self.page.goto(url)
                code = self.page.content()
                code_result = self.text_replace(code)
                # print(code)
                time.sleep(1)
                sku_title_re = re.compile(r'<div class="sku-name">.*?id="bgIcon".*?>(.*?)</div>',re.S)
                sku_title_result = re.findall(sku_title_re, code_result)[0].strip()
                logs.info(sku_title_result)

                if "finalPrice" in code:
                    sku_price_re = re.compile(r'<span class="finalPrice".*?<span class="price">(.*?)</span>', re.S)
                    sku_price_result = re.findall(sku_price_re, code_result)[0].strip()
                    logs.info(f"sku_price_result:{sku_price_result}")
                else:
                    sku_price_re = re.compile(r'<span class="p-price.*?">.*?class="price.*?">(.*?)</span>', re.S)
                    sku_price_result = re.findall(sku_price_re, code_result)[0].strip()
                    logs.info(f"sku_price_result:{sku_price_result}")
                sku_price = {
                    "code": 0,
                    "jingdong_shop":self.shopname,
                    "jingodng_sku":sku,
                    "jingdong_sell_price": sku_price_result,
                    "jingdong_ware_name": sku_title_result,
                }
                return sku_price
            except Exception as e:
                if self.page.query_selector("//div[@class='verifyBtn']"):
                    logs.debug("京东平台突然开始发神经，需要验证")
                    self.page.close()
                    time.sleep(60*60)
                    # update_verify_data = jingdong_verify(self.page).start_jingdong_vrify()
                    # if update_verify_data["status"] == "failed":
                    #     time.sleep(60*60)
                else:
                    logs.error(f"+++++++++++++{e}")
                    update_cookies_dict_data = jingdong_login(self.pw).save_jingdong_cookie()
                    logs.info(update_cookies_dict_data)
                count += 1




    def get_jingdong_sku_price(self):
        """
        skus_price_dict = {
                        "code":0,
                        "jingdong_shop":self.shopname,
                        "jingodng_sku":j.get_attribute("jdprice"),
                        "jingdong_ware_name":i.text_content(),
                        "jingdong_sell_price":j.get_attribute("preprice")
                        }
        """
        skus_price_list = []
        jingdong_skus_urls = self.get_jingdong_skus_urls()
        if jingdong_skus_urls == []:
            logs.info(f"京东搜索 {self.keywords} ：{self.shopname} 未查询到商品")
            skus_price_dict = {"code": 1, "jingdong_shop": self.shopname, "search_result": "未查询到商品"}
            skus_price_list.append(skus_price_dict)
            return skus_price_list
        else:
            for index,jingdong_sku in enumerate(jingdong_skus_urls):
                logs.info(f"===========================================index:{index}===========================================")
                sku_url = jingdong_sku[0]
                sku = jingdong_sku[1]
                sku_price = self.get_sku_price(sku)
                skus_price_list.append(sku_price)
                self.page.close()
                time.sleep(random.randint(2, 5))
            logs.info(f"skus_price_list:{skus_price_list}")
            return skus_price_list

